package XML与JSON.使用DOM;

/*
XML文件不受编程语言和操作系统的限制，因此成为了一种通用的数据交互格式。

下面是以DOM方法解析XML文件。DOM解析以文档树的格式将XML文件全部解析到内存中，因此XML文件的大小将影响到解析时长。

2、代码实操
打开Idea创建项目，在项目下创建student.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<list>
    <!--所有年级-->
    <classes name="班级">
        <grade name="java">
            <gradeName name="一年级"/>
            <gradeName name="二年级"/>
        </grade>
        <grade name="html">
            <gradeName name="三年级"/>
            <gradeName name="四年级"/>
        </grade>
    </classes>
    <!--所有学生-->
    <stuList name="学生">
    <stu name="第一个学生">
        <stuNo name="1001"/>
        <stuName name="张三"/>
    </stu>
    <stu name="第二个学生">
        <stuNo name="1002"/>
        <stuName name="李四"/>
    </stu>
    </stuList>
</list>
创建类Stu,再对XML文件进行增删改查
1、获取Document对象

Document document=null;
private void getDocument() throws ParserConfigurationException, IOException, SAXException {
    //创建解析器工厂
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    //创建解析器对象
    DocumentBuilder builder = factory.newDocumentBuilder();
    //设置解析的xml文件
    document = builder.parse("student.xml");
}
 2、获取根节点

private void getShowInfo() {
    //获取根节点
    Element root = document.getDocumentElement();
    //获取根节点下的子节点集合
    NodeList childNodes = root.getChildNodes();
    //调用遍历子节点集合的方法
    showChildNodes(childNodes);
}
3、获取所有子节点并输出(展示所有的年级和学生信息)

private void showChildNodes(NodeList childNodes) {
    //遍历子节点集合
    for (int i = 0; i < childNodes.getLength(); i++) {
        //获取父节点下每一个子节点
        Node item = childNodes.item(i);
        //判断该节点类型是否为元素节点。这里可以避免下一步操作因空格符导致的类转换失败
        if(item.getNodeType() == Node.ELEMENT_NODE){
            //将Node类型转换为Element类型
            Element ele = (Element) item;
            //输出标签名称和指定属性值
            System.out.println(ele.getTagName()+"\t"+ele.getAttribute("name"));
            //递归，用于输出所有的子节点
            showChildNodes(ele.getChildNodes());
        }
    }
}

4、 实现向XML文件中添加第三个学生王五

private void addInfo() {
    //创建stu元素节点
    Element stu = document.createElement("stu");
    //为stu元素赋予属性
    stu.setAttribute("name","第三个学生");
    //创建stuNo元素节点
    Element type1 = document.createElement("stuNo");
    //为stuNo元素赋予属性
    type1.setAttribute("name","1003");
    //创建stuName元素节点
    Element type2 = document.createElement("stuName");
    //为stuName元素赋予属性
    type2.setAttribute("name","王五");
    //将stuNo和stuName元素作为子节点放入stu元素节点中
    stu.appendChild(type1);
    stu.appendChild(type2);
    //获取根节点
    Element element= document.getDocumentElement();
    //获取根节点下子节点集合
    NodeList childNodes = element.getChildNodes();
    //遍历子节点集合
    for(int i=0;i<childNodes.getLength();i++){
        //获取每个子节点
        Node item = childNodes.item(i);
        //判断该子节点是否是元素节点
        if(item.getNodeType()==Node.ELEMENT_NODE){
           //将节点类型转换为元素类型(Node/Element)
           Element ele = (Element) item;
           //判断name属性是否为学生
           if(ele.getAttribute("name").equals("学生")){
               //在该元素下添加子节点
               ele.appendChild(stu);
           }
        }
     }
     //保存
     save();
}

 增删改操作最后都需要进行转换才能真正的实现数据交互

private void save() {
    try {
        //创建转换器工厂对象
        TransformerFactory factory = TransformerFactory.newInstance();
        //创建转换器对象
        Transformer transformer =factory.newTransformer();
        //设置格式(指定转换器是否进行缩进)
        transformer.setOutputProperty(OutputKeys.INDENT,"yes");
        //设置源(解析XML文件的document对象,这里就是student.xml文件)
        DOMSource source = new DOMSource(document);
        //设置目标位置
        StreamResult result = new StreamResult(new File("student.xml"));
        //进行转换
        transformer.transform(source,result);
    } catch (TransformerException e) {
            throw new RuntimeException(e);
    }
}

5、为所有的年级和学生stu加上编号id

private void updateInfo() {
    //获取所有gradeName年级元素节点
    NodeList gradeList = document.getElementsByTagName("gradeName");
    //遍历gradeName年级元素节点集合
    for(int i=0;i<gradeList.getLength();i++){
        //获取每个gradeName年级元素节点
        Node item = gradeList.item(i);
        //将Node转为Element类型
        Element ele = (Element)item;
        //添加id属性并赋予数值(这里i后面加上""是因为i是int类型加上双引号后自动转型为String类型)
        ele.setAttribute("id",i+"");
    }
    //获取stu所有学生元素节点
    NodeList stuList  = document.getElementsByTagName("stu");
    //遍历stu学生元素节点集合
    for(int i=0;i<stuList.getLength();i++){
        //获取每个stu学生元素节点
        Node item = stuList.item(i);
        //将Node转为Element类型
        Element ele = (Element)item;
        //添加id属性并赋予数值
        ele.setAttribute("id",i+"");
    }
    //保存
    save();
}

6、 删除张三的学生信息

private void deleteInfo() {
    //获取所有stu学生元素节点
    NodeList stuList = document.getElementsByTagName("stu");
    //遍历stu学生元素节点集合
    for(int i = 0;i<stuList.getLength();i++) {
        //获取每个stu学生元素节点并将类型转换为Element类型
        Element item = (Element) stuList.item(i);
        //判断该节点是否是元素节点
        if (item.getNodeType() == Node.ELEMENT_NODE) {
            //获取该学生元素节点下的子节点集合
            NodeList itemer = item.getChildNodes();
            //遍历子节点集合
            for (int j = 0; j < itemer.getLength(); j++) {
                 //获取该子节点
                 Node node = itemer.item(j);
                 //判断是否是元素节点
                 if(node.getNodeType()==Node.ELEMENT_NODE){
                    //转换类型为Element
                    Element element = (Element) node;
                    //判断该元素节点的属性name是否是张三
                    if(element.getAttribute("name").equals("张三")){
                       //删除该节点的父节点
                       item.getParentNode().removeChild(item);
                    }
                 }
             }
         }
     }
     //保存
     save();
}

7、最后main方法执行测试

public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
    Stu stu = new Stu();
    stu.getDocument();
    stu.getShowInfo();
    stu.addInfo();
    stu.updateInfo();
    stu.deleteInfo();
}
3、我的完整代码展示
*/ 
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
 
public class Stu {
    public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
        Stu stu = new Stu();
        stu.getDocument();
        stu.getShowInfo();
        stu.addInfo();
        stu.updateInfo();
        stu.deleteInfo();
    }
 
    Document document=null;
    private void deleteInfo() {
        NodeList stuList = document.getElementsByTagName("stu");
        for(int i = 0;i<stuList.getLength();i++) {
            Element item = (Element) stuList.item(i);
            if (item.getNodeType() == Node.ELEMENT_NODE) {
                NodeList itemer = item.getChildNodes();
                for (int j = 0; j < itemer.getLength(); j++) {
                    Node node = itemer.item(j);
                    if(node.getNodeType()==Node.ELEMENT_NODE){
                        Element element = (Element) node;
                        if(element.getAttribute("name").equals("张三")){
                            item.getParentNode().removeChild(item);
                        }
                    }
                }
            }
        }
        save();
    }
    private void updateInfo() {
        NodeList gradeList = document.getElementsByTagName("gradeName");
        for(int i=0;i<gradeList.getLength();i++){
            Node item = gradeList.item(i);
            Element ele = (Element)item;
            ele.setAttribute("id",i+"");
        }
        NodeList stuList  = document.getElementsByTagName("stu");
        for(int i=0;i<stuList.getLength();i++){
            Node item = stuList.item(i);
            Element ele = (Element)item;
            ele.setAttribute("id",i+"");
        }
        save();
    }
 
    private void addInfo() {
        Element stu = document.createElement("stu");
        stu.setAttribute("name","第三个学生");
        Element type1 = document.createElement("stuNo");
        type1.setAttribute("name","1003");
        Element type2 = document.createElement("stuName");
        type2.setAttribute("name","王五");
        stu.appendChild(type1);
        stu.appendChild(type2);
        Element element= document.getDocumentElement();
        NodeList childNodes = element.getChildNodes();
        for(int i=0;i<childNodes.getLength();i++){
            Node item = childNodes.item(i);
            if(item.getNodeType()==Node.ELEMENT_NODE){
                Element ele = (Element) item;
                if(ele.getAttribute("name").equals("学生")){
                    ele.appendChild(stu);
                }
            }
        }
        save();
    }
 
    private void save() {
        TransformerFactory factory = TransformerFactory.newInstance();
        try {
            Transformer transformer = factory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT,"yes");
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(new File("student.xml"));
            transformer.transform(source,result);
        } catch (TransformerException e) {
            throw new RuntimeException(e);
        }
    }
 
    private void getShowInfo() {
        Element root = document.getDocumentElement();
        NodeList childNodes = root.getChildNodes();
        showChildNodes(childNodes);
    }
 
    private void showChildNodes(NodeList childNodes) {
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item = childNodes.item(i);
            if(item.getNodeType() == Node.ELEMENT_NODE){
                Element ele = (Element) item;
                System.out.println(ele.getTagName()+"\t"+ele.getAttribute("name"));
                showChildNodes(ele.getChildNodes());
            }
        }
    }
 
 
    private void getDocument() throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        document = builder.parse("student.xml");
    }
}
//这是以DOM的方式解析XML文件的基本练习
